package com.example.demo.config;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.example.demo.util.EmptyUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * @title:	MybatisConfig
 * @author:	许子文
 * @date:	2019年12月30日 
 * @descirption: 如果要配置多数据源的话就再写一个这个配置类，然后把对应的扫描包、扫描实体类以及扫描xml文件都换上对应的路径，方法上不要加@Primary注解
 * 				，调用对应的mapper类，就可以时间多数据源配置
 */
@Slf4j
@Configuration
@MapperScan(basePackages = {"com.example.demo.*.dao"},sqlSessionFactoryRef="masterSqlSessionFactory")
public class MybatisConfig {
	
	@Autowired
	private Environment environment;
	
	@Value("${mybatis-plus.master.mapper-locations}")
	private String mapperLocations;
	
	@Bean(name="masterDataSource",destroyMethod="close")
	@Primary
	public DataSource masterDataSource() {
		DruidDataSource dataSource = new DruidDataSource();
		
		dataSource.setDriverClassName(environment.getProperty("spring.datasource.driver-class-name"));
		dataSource.setUrl(environment.getProperty("spring.datasource.url"));
		dataSource.setUsername(environment.getProperty("spring.datasource.username"));
		dataSource.setPassword(environment.getProperty("spring.datasource.password"));
		dataSource.setInitialSize(2);
		dataSource.setMaxActive(20);
		dataSource.setMinIdle(0);
		dataSource.setMaxWait(60000);
		dataSource.setValidationQuery("select 1");
		dataSource.setTestOnBorrow(false);
		dataSource.setTestWhileIdle(true);
		dataSource.setPoolPreparedStatements(false);
		/** 去掉druid的服务监听,不然不可以执行多条sql语句 **/
		/*try {
			dataSource.setFilters(environment.getProperty("spring.datasource.druid.filters"));
		} catch (Exception e) {
			logger.error("添加sql监控配置界面失败",e);
			return null;
		}*/
		
		log.debug("主数据库连接创建");

		return dataSource;
	}
	
	@Bean(name="masterSqlSessionFactory")
	@Primary
	public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource")DataSource dataSource) throws Exception {
		log.debug("开始创建会话工厂");
		//mybatis配置
		/*SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(dataSource);
		bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(environment.getProperty("mybatis-plus.master.mapper-locations")));
		bean.setTypeAliasesPackage(environment.getProperty("mybatis-plus.master.type-aliases-package"));
		//设置用map接收返回值的时候,值为null时属性存在
		org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
		configuration.setCallSettersOnNulls(true);
		bean.setConfiguration(configuration);
		logger.debug("主会话工厂创建");
		return bean.getObject();*/
		
		//mybatisplus配置
		MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
		bean.setDataSource(dataSource);
		log.debug("mybatis-plus.master.mapper-locations>>>{}",JSONObject.toJSONString(mapperLocations));
		bean.setMapperLocations(resolveMapperLocations());
		bean.setTypeAliasesPackage(environment.getProperty("mybatis-plus.master.type-aliases-package"));
		MybatisConfiguration configuration = new MybatisConfiguration();
		configuration.setCallSettersOnNulls(true);
		configuration.setMapUnderscoreToCamelCase(false);
		bean.setConfiguration(configuration);
		//增加此行解决mybatis打包实体类别名失效的问题
		bean.setVfs(MySpringBootVFS.class);
		log.debug("主会话工厂创建");
		return bean.getObject();
	}
	
	private Resource[] resolveMapperLocations() {
		ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
		
		String[] mapperPathArray = mapperLocations.split(",");
		
		List<Resource> resources = new ArrayList<>();
		
		if(EmptyUtil.isNotEmpty(mapperPathArray)) {
			try {
				for (int i = 0; i < mapperPathArray.length; i++) {
					Resource[] mappers = resourceResolver.getResources(mapperPathArray[i]);
					resources.addAll(Arrays.asList(mappers));
				}
			} catch (Exception e) {
				log.error("解析mybatis的xml路径失败",e);
			}
		}
		
		return resources.toArray(new Resource[resources.size()]);
	}
	
}
